/*
 * @Author: aggfb 714740235@qq.com
 * @Date: 2024-05-18 14:29:52
 * @LastEditors: aggfb 714740235@qq.com
 * @LastEditTime: 2024-05-18 20:45:45
 * @FilePath: \2.code\label_rack_control\firmware\bsp\bsp_flash.c
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */

#include "bsp_flash.h"
#include "apm32f10x_conf.h"

void bsp_flash_erase_page(uint32_t add)
{
    #ifdef MCU_TYPE_APM
    FMC_Unlock();
    FMC_ClearStatusFlag((FMC_FLAG_T)(FMC_FLAG_OC | FMC_FLAG_PE | FMC_FLAG_WPE));
    FMC_ErasePage(add);
    FMC_ClearStatusFlag((FMC_FLAG_T)(FMC_FLAG_OC | FMC_FLAG_PE | FMC_FLAG_WPE));
    FMC_Lock();
    #else
    FLASH_Unlock();                                                                            
    FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR); 
    FLASH_ErasePage(add);                                                     
    FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
    FLASH_Lock();       
    #endif
}

/**
 * @brief 
 * 
 * @param add 
 * @param dat 
 */
void bsp_flash_write(uint32_t add, uint16_t dat)
{
    #ifdef MCU_TYPE_APM
    FMC_Unlock();
    FMC_ClearStatusFlag((FMC_FLAG_T)(FMC_FLAG_OC | FMC_FLAG_PE | FMC_FLAG_WPE));
    FMC_ProgramWord(add, dat);
    FMC_ClearStatusFlag((FMC_FLAG_T)(FMC_FLAG_OC | FMC_FLAG_PE | FMC_FLAG_WPE));
    FMC_Lock();
    #else
    FLASH_Unlock();                                                                            
    FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR); 
    FLASH_ProgramHalfWord(add, dat);                                                        
    FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
    FLASH_Lock();  
    #endif                                                                         
}

void bsp_flash_write_buff(uint32_t add , uint16_t* buf, uint16_t len)
{
    uint32_t myAddr = add;
    #ifdef MCU_TYPE_APM
    FMC_Unlock();
    FMC_ClearStatusFlag((FMC_FLAG_T)(FMC_FLAG_OC | FMC_FLAG_PE | FMC_FLAG_WPE));
    FMC_ErasePage(add);
    while (len--)
    {
        FMC_STATUS_T res = FMC_ProgramWord(myAddr, *buf++);
        if(FMC_STATUS_COMPLETE != res)
        {
            FMC_ClearStatusFlag((FMC_FLAG_T)(FMC_FLAG_OC | FMC_FLAG_PE | FMC_FLAG_WPE));
            FMC_Lock();
            return;  
        }
        myAddr += 2;
    }
    FMC_ClearStatusFlag((FMC_FLAG_T)(FMC_FLAG_OC | FMC_FLAG_PE | FMC_FLAG_WPE));
    FMC_Lock();  
    #else
    FLASH_Unlock();                                                                            
    FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR); 
    FLASH_ErasePage(myAddr);                                                                  
    while (len--)
    {
        FLASH_ProgramHalfWord(myAddr, *buf++);
        myAddr += 2;
    }
    FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
    FLASH_Lock();    
    #endif                                                                             
}

void bsp_flash_read_buff(uint32_t add , uint16_t* buf, uint16_t len)
{
    uint32_t myAddr = add;
    uint16_t *ptr = buf;
    while (len--)
    {
        *ptr++ = *(uint8_t *)myAddr;
        myAddr += 2;
    }
}

uint16_t bsp_flash_read(uint32_t add)
{
    uint16_t a;
    a = *(uint16_t *)(add);
    return a;
}
